package com.elitel.frame.base.service.impl;

import com.elitel.common.utils.XCommonUtils;
import com.elitel.frame.base.component.RedisCacheComponent;
import com.elitel.frame.base.service.BaseFieldenumService;
import com.elitel.frame.base.service.CfgFieldService;
import com.elitel.frame.base.utils.IdWorker2;
import com.elitel.frame.main.dao.CfgFieldCustomFilterMapper;
import com.elitel.frame.main.dao.CfgFieldMapper;
import com.elitel.frame.main.dao.ext.ExtBaseFieldconfigMapper;
import com.elitel.frame.main.dao.ext.ExtCfgFieldMapper;
import com.elitel.frame.main.dao.ext.ExtCfgTableMapper;
import com.elitel.frame.main.entity.BaseFieldenum;
import com.elitel.frame.main.entity.CfgField;
import com.elitel.frame.main.entity.CfgFieldCustomFilter;
import com.elitel.frame.main.entity.CfgTable;
import com.elitel.frame.main.entity.ext.BaseFieldconfigExt;
import com.elitel.frame.main.entity.vo.ZTreeDataModelVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author guoyanfei
 * @Description 数据库表字段配置服务实现类
 */
@Service
public class CfgFieldServiceImpl implements CfgFieldService {

    @Autowired
    private ExtCfgFieldMapper extCfgFieldMapper;
    @Autowired
    private CfgFieldMapper cfgfieldMapper;
    @Autowired
    private ExtCfgTableMapper extCfgTableMapper;
    @Autowired
    private ExtBaseFieldconfigMapper extBaseFieldconfigMapper;
    @Autowired
    private RedisCacheComponent redisCacheComponent;
    @Autowired
    private BaseFieldenumService baseFieldenumService;
    @Autowired
    private IdWorker2 idWorker2;

    @Override
    public List<CfgField> selectFieldByConfig(String dtConfigId) {
        List<CfgField> list = extCfgFieldMapper.selectFieldByConfig(dtConfigId);
        return list;
    }


    @Override
    public List<CfgField> getAllField(String dtConfigId) {
        return extCfgFieldMapper.getAllFieldList(dtConfigId);
    }

    @Override
    public void batchAddFields(String dtConfigId, String strFields, String action, boolean isImport) {
        if (XCommonUtils.isEmpty(strFields))
            return;

        //1、分割字符串成功字段数组
        String[] arrField = strFields.split("\\|");
        //2、通过dtConfigId查询表实体
        CfgTable cfgTable = extCfgTableMapper.getInfoByDtconfigId(dtConfigId);
        //3、查询排序序号
        int dforder = 1;
        Integer strorderInteger = extCfgFieldMapper.getMaxdfOrder(dtConfigId);

        if (strorderInteger != null)
            dforder = strorderInteger.intValue() + 1;

        for (int i = 0; i < arrField.length; i++) {
            String[] fieldname = arrField[i].split("-");
            Date datenow = new Date();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            CfgField cfgField = new CfgField();
            cfgField.setGuid(UUID.randomUUID().toString());
            cfgField.setDtConfigId(dtConfigId);
            cfgField.setDtName(cfgTable.getDtName());
            cfgField.setDfName(fieldname[0]);
            if (fieldname[1] != null && !fieldname[1].equals("") && !fieldname[1].toLowerCase().equals("null")
                    && !fieldname[1].equals(" ")) {
                cfgField.setDfNameCn(fieldname[1]);
            } else {
                cfgField.setDfNameCn(fieldname[0]);
            }

            cfgField.setDtType(fieldname[2].toLowerCase());
//					if(fieldname[2].toLowerCase().equals("date") || fieldname[2].toLowerCase().equals("timestamp")
//							|| fieldname[2].toLowerCase().equals("time") || fieldname[2].toLowerCase().equals("datetime")){
//						cfgField.setDtType("date");
//					}else if(fieldname[2].toLowerCase().indexOf("char") >= 0 || fieldname[2].toLowerCase().indexOf("text") > 0) {
//						cfgField.setDtType("string");
//					}else {
//						cfgField.setDtType("int");
//					}
            cfgField.setDfOrder(dforder);

            //设置主键字段
            if (cfgTable.getDtPrimarykey() != null &&
                    !cfgTable.getDtPrimarykey().equals("")) {
                cfgField.setDfIsprimarykey(0);
                String[] pknames = cfgTable.getDtPrimarykey().split(",");
                for (String pkname : pknames) {
                    if (pkname.equals(fieldname[0])) {
                        cfgField.setDfIsprimarykey(1);
                    }
                }

            } else {
                cfgField.setDfIsprimarykey(0);
            }
            cfgField.setCreatedate(dateFormat.format(datenow));

            if (action.equals("update")) {
                //获取该字段原来的主键guid以更新
                String guid = "";
                try {
                    guid = extCfgFieldMapper.selectFieldInfo(dtConfigId, fieldname[0]).getGuid();
                } catch (Exception e) {//若源库中新增了，但服务中不存在该字段，则更新插入
                    cfgfieldMapper.insertSelective(cfgField);
                }
                if (isImport) {//初始装载（load）时不覆盖服务中已存在的字段信息，但外部修改导入（import）时进行字段信息的覆盖更新
                    int order = extCfgFieldMapper.selectFieldInfo(dtConfigId, fieldname[0]).getDfOrder();
                    cfgField.setGuid(guid);
                    cfgField.setDfOrder(order);
                    cfgfieldMapper.updateByPrimaryKeySelective(cfgField);
                }
            } else if (action.equals("add")) {
                cfgfieldMapper.insertSelective(cfgField);
                dforder++;
            }
        }
        redisCacheComponent.freshCfgFieldRedisCache(dtConfigId);
    }


    @Override
    public void addFieldList(List<CfgField> cfgFieldList) {
        if (XCommonUtils.isEmpty(cfgFieldList))
            return;


        String dtConfigId = cfgFieldList.get(0).getDtConfigId();
        //2、通过dtConfigId查询表实体
        CfgTable cfgTable = extCfgTableMapper.getInfoByDtconfigId(dtConfigId);
        //3、查询排序序号
        int dforder = 1;
        Integer strorderInteger = extCfgFieldMapper.getMaxdfOrder(dtConfigId);

        if (strorderInteger != null)
            dforder = strorderInteger.intValue() + 1;


        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        for (CfgField cfgField : cfgFieldList) {
            Date datenow = new Date();
            cfgField.setGuid(UUID.randomUUID().toString());
            cfgField.setDtConfigId(dtConfigId);
            cfgField.setDtType(cfgField.getDtType().toLowerCase());
            cfgField.setDfOrder(dforder);

            //设置主键字段
            if (XCommonUtils.isNotEmpty(cfgTable.getDtPrimarykey())) {
                cfgField.setDfIsprimarykey(0);
                String[] pknames = cfgTable.getDtPrimarykey().split(",");
                for (String pkname : pknames) {
                    if (pkname.equals(cfgField.getDfName())) {
                        cfgField.setDfIsprimarykey(1);
                    }
                }
            } else {
                cfgField.setDfIsprimarykey(0);
            }

            cfgField.setCreatedate(dateFormat.format(datenow));
            cfgfieldMapper.insertSelective(cfgField);
            dforder++;
        }
    }


    /*
     * Modify By CocoLiu 2017/10/17
     * 删除字段逻辑有问题，先把表ID拿到，然后删除，最后更新缓存数据。
     * @see com.elitel.frame.base.service.CfgFieldService#deleteBatchByGuid(java.util.List)
     */
    @Override
    public void deleteBatchByGuid(List<String> guids) {
        List<String> ConfigIDs = new ArrayList();
        for (String str : guids) {
            CfgField cfgField = cfgfieldMapper.selectByPrimaryKey(str);
            ConfigIDs.add(cfgField.getDtConfigId().toString());
        }
        extCfgFieldMapper.deleteBatchByGuid(guids);
        for (String sConfigID : guids) {
            redisCacheComponent.freshCfgFieldRedisCache(sConfigID);
        }
    }

    @Override
    public int updateFieldInfo(CfgField cfgField) {
        int updateByPrimaryKeySelective = cfgfieldMapper.updateByPrimaryKeySelective(cfgField);
        redisCacheComponent.freshCfgFieldRedisCache(cfgField.getDtConfigId());
        return updateByPrimaryKeySelective;
    }

    @Override
    public int updateFieldInfoList(List<CfgField> cfgFieldList) {
        int count = 0;
        for (CfgField cfgField : cfgFieldList) {
            count += updateFieldInfo(cfgField);
        }
        return count;
    }


    @Override
    public List<CfgField> selectFieldNotInFieldConfig(String dtconfig) {
        return extCfgFieldMapper.selectFieldNotInFieldConfig(dtconfig);
    }

    @Override
    public List<ZTreeDataModelVo> selectFieldToJoinTable(String dtconfig) {
        List<ZTreeDataModelVo> zTreeDataModelVos = new ArrayList<>();
        try {
            //通过视图标识查询表标识
            String newdtconfig = "";
            CfgTable viewtable = extCfgTableMapper.getInfoByDtconfigId(dtconfig);
            if (viewtable != null) {
                newdtconfig = viewtable.getDtName();
            }
            //1、设置主表
            CfgTable cfgTables = extCfgTableMapper.queryCfgTable(newdtconfig);
            List<CfgField> cfgFields = extCfgFieldMapper.getAllFieldList(newdtconfig);
            if (cfgTables != null && cfgFields != null && cfgFields.size() > 0) {
                ZTreeDataModelVo zts = new ZTreeDataModelVo();
                //设置主表名称
                zts.setId(dtconfig);
                zts.setName(cfgTables.getDtNameCn() + "(" + cfgTables.getDtName() + ")-[AA]");
                zts.setHint("AA");
                //设置主表字段名称
                List<ZTreeDataModelVo> ztchilds = new ArrayList<>();
                for (CfgField cfgField : cfgFields) {
                    ZTreeDataModelVo ztchild = new ZTreeDataModelVo();
                    ztchild.setId(cfgField.getGuid());
                    ztchild.setName(cfgField.getDfNameCn() + "(" + cfgField.getDfName() + ")");
                    //表别名
                    ztchild.setHint("AA");
                    //是否是枚举字段
                    ztchild.setIsMark("0");
                    ztchilds.add(ztchild);
                }
                //设置字段枚举
                ztchilds.addAll(getFieldEnum(newdtconfig, "AA"));

                zts.setChildren(ztchilds);
                zTreeDataModelVos.add(zts);
            }

            //2、设置外键表
            List<BaseFieldconfigExt> bfs = extBaseFieldconfigMapper.getAllFieldConfig(dtconfig);
            if (cfgTables != null && bfs != null && bfs.size() > 0) {
                for (BaseFieldconfigExt baseFieldconfigExt : bfs) {
                    if (baseFieldconfigExt.getForeignType().equals("1")) {//表连接
                        CfgTable cfgforegintable = extCfgTableMapper.getInfoByDtconfigId(baseFieldconfigExt.getForeignTable());
                        if (cfgforegintable != null) {
                            //设置外键表名称
                            ZTreeDataModelVo ztforegin = new ZTreeDataModelVo();
                            ztforegin.setId(cfgforegintable.getDtConfigId());
                            ztforegin.setName(cfgforegintable.getDtNameCn() + "(" + cfgforegintable.getDtName() + ")-[" + baseFieldconfigExt.getAltername() + "]");
                            ztforegin.setHint(baseFieldconfigExt.getAltername());
                            //设置外键表字段名称
                            List<ZTreeDataModelVo> ztforegins = new ArrayList<>();
                            List<CfgField> cfgFieldForegin = extCfgFieldMapper.getAllFieldList(cfgforegintable.getDtConfigId());
                            for (CfgField cfgFForegin : cfgFieldForegin) {
                                ZTreeDataModelVo ztf = new ZTreeDataModelVo();
                                ztf.setId(cfgFForegin.getGuid());
                                ztf.setName(cfgFForegin.getDfNameCn() + "(" + cfgFForegin.getDfName() + ")-[" + baseFieldconfigExt.getAltername() + "]");
                                //表别名
                                ztf.setHint(baseFieldconfigExt.getAltername());
                                //是否是枚举字段
                                ztf.setIsMark("0");
                                ztforegins.add(ztf);
                            }
                            //设置字段枚举
                            ztforegins.addAll(getFieldEnum(cfgforegintable.getDtConfigId(), baseFieldconfigExt.getAltername()));
                            ztforegin.setChildren(ztforegins);
                            zTreeDataModelVos.add(ztforegin);
                        }

                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return zTreeDataModelVos;
    }

    /**
     * @param dtConfigId(表标识)
     * @param alterName(别名)
     * @return ZTreeDataModelVo集合
     * @description 查询字段枚举
     * @author guoyanfei
     * @date 2017/11/30
     */
    private List<ZTreeDataModelVo> getFieldEnum(String dtConfigId, String alterName) {
        List<ZTreeDataModelVo> zTreeDataModelVos = new ArrayList<ZTreeDataModelVo>();
        List<BaseFieldenum> baseFieldenums = baseFieldenumService.getBaseFieldenumList(dtConfigId);
        if (baseFieldenums != null && baseFieldenums.size() > 0) {
            for (BaseFieldenum baseFieldenum : baseFieldenums) {
                ZTreeDataModelVo zTreeDataModelVo = new ZTreeDataModelVo();
                zTreeDataModelVo.setId(baseFieldenum.getGuid());
                zTreeDataModelVo.setName(baseFieldenum.getEnumcode() + "(" + baseFieldenum.getEnumname() + ")");
                //表别名
                zTreeDataModelVo.setHint(alterName);
                //是否是枚举字段
                zTreeDataModelVo.setIsMark("1");
                zTreeDataModelVos.add(zTreeDataModelVo);
            }
        }
        return zTreeDataModelVos;
    }

    @Override
    public CfgField selectFieldByguid(String guid) {
        return cfgfieldMapper.selectByPrimaryKey(guid);
    }

    @Override
    public void batchInsertCfgField(List<CfgField> cfgFieldList) {
        if (cfgFieldList == null || cfgFieldList.size() == 0) {
            return;
        }
        cfgfieldMapper.batchInsertCfgField(cfgFieldList);
    }
    @Resource
    CfgFieldCustomFilterMapper cfgFieldCustomFilterMapper;

    @Override
    public void saveCustomFilterField(List<CfgFieldCustomFilter> cfgFieldCustomFilters, String dtConfigId) {
        cfgFieldCustomFilterMapper.delete(dtConfigId);
        for (CfgFieldCustomFilter cfgFieldCustomFilter : cfgFieldCustomFilters) {
            cfgFieldCustomFilter.setGuid(IdWorker2.createStrId());
            cfgFieldCustomFilterMapper.insert(cfgFieldCustomFilter);
        }
    }

    @Override
    public List<CfgFieldCustomFilter> getCustomFilterField(String dtConfigId) {
      return   cfgFieldCustomFilterMapper.getAll(dtConfigId);
    }
}
